﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Coder
{
    //Returns a "Language" object with name, version, id, template, and example properties.
    public class Language
    {
        public string Name { get; set; }
        public string Version { get; set; }
        public int LanguageID { get; set; }
        public string Template { get; set; }
        public string Example { get; set; }


        /// <summary>
        /// Represents all the languages in the IdeOne Framework.
        /// </summary>
        #region Language List

        /*
         * Default Key Words
         * Color Codes
         * Level 0: Blue 
         * Level 1: Red
         * Level 2: Purple
         */
        public Dictionary<string, int> KeyWords = new Dictionary<string, int>() {{"public", 0},
                        {"protected", 0},
                        {"internal", 0},
                        {"private", 0},
                        {"friend", 0},
                        {"boolean", 1},
                        {"bool", 1},
                        {"byte", 1},
                        {"char", 1},
                        {"string", 1},
                        {"decimal", 1},
                        {"short", 1},
                        {"integer", 1},
                        {"long", 1},
                        {"single", 1},
                        {"double", 1},
                        {"int", 1},
                        {"float", 1},
                        {"sbyte", 1},
                        {"ushort", 1},
                        {"object", 1},
                        {"signed", 1},
                        {"unsigned", 1},
                        {"void", 1},
                        {"static", 2},
                        {"args", 2},
                        {"this", 2},
                        {"type", 2}};


        /// <summary>
        /// Retrieves a language depending on the languageID.
        /// </summary>
        /// <param name="languageId">The languageID the user chose.</param>
        /// <returns>Returns a Language or an Exception stating that it cannot find the specified language.</returns>
        public static Language RetrieveLanguage(int languageId)
        {
            foreach (Language lang in GlobalLanguageList)
            {
                if (lang.LanguageID == languageId)
                {
                    return lang;
                }
            }
            throw new Exception("Cannot find Language!");
        }

        public static List<Language> GlobalLanguageList = new List<Language>()
        {
                        new Language() { Name= "Ada", Version= "gnat-4.5.2", LanguageID= 7, Template= "", Example= "" },
                        new Language(){ Name= "Assembler", Version= "nasm-2.07", LanguageID= 13, Template= "", Example= "" },
                        new Language(){ Name= "AWK (gawk)", Version= "gawk-3.1.6", LanguageID= 104, Template= "", Example= "" },
                        new Language(){ Name= "Bash", Version= "bash 4.0.35", LanguageID= 28, Template= "", Example= "" },
                        new Language(){ Name= "bc", Version= "bc-1.06.95", LanguageID= 110, Template= "", Example= "" },
                        new Language(){ Name= "Brainf**k", Version= "bff-1.0.3.1", LanguageID= 12, Template= ">+[>>,----------[>,----------]+++++[<-------->-]<[>>-<]>+[\r-<+++++++[<------>-]<[>>-<]>+[\r-<<[>>-<]>+[<<->>->]>\r]<+++++++[<++++++>-]>>\r]<++++++++[<+++++>-]<\r[<]<[>>[++++++++++.>]++++++++++.[[-]<]]<] \r", Example= "" },
                        new Language(){ Name= "C", Version= "gcc-4.3.4", LanguageID= 11, Template= "#include <stdio.h> \r int main(void) { \r \t return 0; \r }", Example= "#include <stdio.h> \r\rint main(void) { \r  int x; \r  for(; scanf(\"%d\",&x) > 0 && x != 42; printf(\"%d\\n\", x)); \r  return 0; \r}  \r" },
                        new Language(){ Name= "C#", Version= "mono-2.8", LanguageID= 27, Template= "using System;\r\rpublic class Test\r{\r\tpublic static void Main()\r\t{\r\t\t\r\t}\r} \r", 
                            Example= "using System;\rpublic class Test\r{\r\tpublic static void Main()\r\t{\r\t\tint n;\r\t\twhile ((n = int.Parse(Console.ReadLine()))!=42)\r\t\t\tConsole.WriteLine(n);\r\t}\r} \r", 
                            KeyWords = new Dictionary<string,int>() {
                        {"public", 0},
                        {"protected", 0},
                        {"internal", 0},
                        {"private", 0},
                        {"friend", 0},
                        {"boolean", 1},
                        {"bool", 1},
                        {"byte", 1},
                        {"char", 1},
                        {"string", 1},
                        {"decimal", 1},
                        {"short", 1},
                        {"integer", 1},
                        {"long", 1},
                        {"single", 1},
                        {"double", 1},
                        {"int", 1},
                        {"float", 1},
                        {"sbyte", 1},
                        {"ushort", 1},
                        {"object", 1},
                        {"signed", 1},
                        {"unsigned", 1},
                        {"void", 1},
                        {"static", 2},
                        {"args", 2},
                        {"this", 2},
                        {"type", 2}
                        }},
                        new Language(){ Name= "C++", Version= "gcc-4.3.4", LanguageID= 1, Template= "#include <iostream>\r\rusing namespace std;\r\rint main() {\r\t\r\treturn 0;\r} \r", Example= "#include <iostream>\rusing namespace std;\r\rint main() {\r\r\tint intNum = 0;\r\t\r\tcin >> intNum;\r\twhile (intNum != 42) {\r\t\tcout << intNum << \"\\n\";\r\t\tcin >> intNum;\r\t}\r\r\treturn 0;\r\r} \r" },
                        new Language(){ Name= "C++0x", Version= "gcc-4.5.1", LanguageID= 44, Template= "", Example= "" },
                        new Language(){ Name= "C99 strict", Version= "gcc-4.3.4", LanguageID= 34, Template= "", Example= "" },
                        new Language(){ Name= "CLIPS", Version= "clips 6.24", LanguageID= 14, Template= "", Example= "" },
                        new Language(){ Name= "Clojure", Version= "clojure 1.3", LanguageID= 111, Template= "", Example= "" },
                        new Language(){ Name= "COBOL", Version= "open-cobol-1.0", LanguageID= 118, Template= "", Example= "" },
                        new Language(){ Name= "Common Lisp (clisp)", Version= "clisp 2.47", LanguageID= 32, Template= "", Example= "" },
                        new Language(){ Name= "D (dmd)", Version= "dmd-2.042", LanguageID= 102, Template= "", Example= "" },
                        new Language(){ Name= "Erlang", Version= "erl-5.7.3", LanguageID= 36, Template= "", Example= "" },
                        new Language(){ Name= "F#", Version= "fsharp-2.0.0", LanguageID= 124, Template= "", Example= "" },
                        new Language(){ Name= "Factor", Version= "factor-0.93", LanguageID= 123, Template= "", Example= "" },
                        new Language(){ Name= "Falcon", Version= "falcon-0.9.6.6", LanguageID= 125, Template= "", Example= "" },
                        new Language(){ Name= "Forth", Version= "gforth-0.7.0", LanguageID= 107, Template= "", Example= "" },
                        new Language(){ Name= "Fortran", Version= "gfortran-4.3.4", LanguageID= 5, Template= "", Example= "" },
                        new Language(){ Name= "Go", Version= "gc-2010-07-14", LanguageID= 114, Template= "", Example= "" },
                        new Language(){ Name= "Groovy", Version= "groovy-1.8.6", LanguageID= 121, Template= "", Example= "" },
                        new Language(){ Name= "Haskell", Version= "ghc-6.8.2", LanguageID= 21, Template= "", Example= "" },
                        new Language(){ Name= "Icon", Version= "iconc 9.4.3", LanguageID= 16, Template= "", Example= "" },
                        new Language(){ Name= "Intercal", Version= "c-intercal 28.0-r1", LanguageID= 9, Template= "", Example= "" },
                        new Language(){ Name= "Java", Version= "sun-jdk-1.6.0.31", LanguageID= 10, Template= "import java.util.*;\rimport java.lang.*;\r\rclass Main\r{\r\tpublic static void main (String[] args) throws java.lang.Exception\r\t{\r\t\t\r\t}\r} \r",
                            Example= "class Main\r{\r  public static void main (String[] args) throws java.lang.Exception\r  {\r     java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));\r     String s;\r     while (!(s=r.readLine()).startsWith(\"42\")) System.out.println(s);\r  }\r} \r" },
                        new Language(){ Name= "Java7", Version= "sun-jdk-1.7.0_03", LanguageID= 10, Template= "import java.util.*;\rimport java.lang.*;\r\rclass Main\r{\r\tpublic static void main (String[] args) throws java.lang.Exception\r\t{\r\t\t\r\t}\r} \r", 
                            Example= "class Main\r{\r  public static void main (String[] args) throws java.lang.Exception\r  {\r     java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));\r     String s;\r     while (!(s=r.readLine()).startsWith(\"42\")) System.out.println(s);\r  }\r} \r" },
                        new Language(){ Name= "JavaScript (rhino)", Version= "rhino-1.6.5", LanguageID= 35, Template= "", Example= "" },
                        new Language(){ Name= "JavaScript (spLanguageIDermonkey)", Version= "spLanguageIDermonkey-1.7", LanguageID= 112, Template= "", Example= "" },
                        new Language(){ Name= "Lua", Version= "luac 5.1.4", LanguageID= 26, Template= "", Example= "" },
                        new Language(){ Name= "Nemerle", Version= "spLanguageIDermonkey-1.7", LanguageID= 30, Template= "", Example= "" },
                        new Language(){ Name= "Nice", Version= "nicec 0.9.6", LanguageID= 25, Template= "", Example= "" },
                        new Language(){ Name= "Nimrod", Version= "nimrod-0.8.8", LanguageID= 122, Template= "", Example= "" },
                        new Language(){ Name= "Node.js", Version= "0.8.11", LanguageID= 56, Template= "", Example= "" },
                        new Language(){ Name= "Objective-C", Version= "gcc-4.5.1", LanguageID= 43, Template= "", Example= "" },
                        new Language(){ Name= "Ocaml", Version= "ocamlopt 3.10.2", LanguageID= 8, Template= "", Example= "" },
                        new Language(){ Name= "Oz", Version= "mozart-1.4.0", LanguageID= 119, Template= "", Example= "" },
                        new Language(){ Name= "PARI/GP", Version= "2.5.1", LanguageID= 57, Template= "", Example= "" },
                        new Language(){ Name= "Pascal (fpc)", Version= "fpc 2.2.0", LanguageID= 22, Template= "", Example= "" },
                        new Language(){ Name= "Pascal (gpc)", Version= "gpc 20070904", LanguageID= 2, Template= "", Example= "" },
                        new Language(){ Name= "Perl", Version= "perl 5.12.1", LanguageID= 3, Template= "#!/usr/bin/perl", Example= "#!/usr/bin/perl \r while (($_=<>)!=42) {print $_;}" },
                        new Language(){ Name= "Perl 6", Version= "rakudo-2010.08", LanguageID= 54, Template= "#!/usr/bin/perl", Example= "#!/usr/bin/perl \r while (($_=<>)!=42) {print $_;}" },
                        new Language(){ Name= "PHP", Version= "php 5.2.11", LanguageID= 29, Template= "<?php \r?>", Example= "<?php\r\r  $hi = fopen('php://stdin', \"r\");\r  $ho = fopen('php://stdout', \"w\");\r\r  while (true) \r  {\r    fscanf($hi, \"%d\", $n);\r    if ($n == 42)\r      break;\r    fwrite($ho, sprintf(\"%d\\n\", $n));\r  }\r\r  fclose($ho);\r  fclose($hi);\r?> \r" },
                        new Language(){ Name= "Pike", Version= "pike 7.6.86", LanguageID= 19, Template= "", Example= "" },
                        new Language(){ Name= "Prolog (gnu)", Version= "gprolog-1.3.1", LanguageID= 108, Template= "", Example= "" },
                        new Language(){ Name= "Prolog (swi)", Version= "swipl 5.6.64", LanguageID= 15, Template= "", Example= "" },
                        new Language(){ Name= "Python", Version= "python 2.7.2", LanguageID= 4, Template= "n = int(raw_input())\rwhile n != 42:\r    print n\r    n = int(raw_input()) \r", Example= "" },
                        new Language(){ Name= "Python 3", Version= "python-3.1.2", LanguageID= 116, Template= "n = int(raw_input())\rwhile n != 42:\r    print n\r    n = int(raw_input()) \r", Example= "" },
                        new Language(){ Name= "R", Version= "R-2.11.1", LanguageID= 117, Template= "", Example= "" },
                        new Language(){ Name= "Ruby", Version= "ruby-1.9.3", LanguageID= 17, Template= "", Example= "" },
                        new Language(){ Name= "Scala", Version= "scala-2.9.1", LanguageID= 39, Template= "", Example= "" },
                        new Language(){ Name= "Scheme (guile)", Version= "guile 1.8.5", LanguageID= 33, Template= "", Example= "" },
                        new Language(){ Name= "Smalltalk", Version= "gst 3.1", LanguageID= 23, Template= "", Example= "" },
                        new Language(){ Name= "SQL", Version= "sqlite3-3.7.3", LanguageID= 40, Template= "", Example= "" },
                        new Language(){ Name= "Tcl", Version= "tclsh 8.5.7", LanguageID= 38, Template= "", Example= "" },
                        new Language(){ Name= "Text", Version= "tclsh 8.5.7", LanguageID= 62, Template= "", Example= "" },
                        new Language(){ Name= "Unlambda", Version= "unlambda-2.0.0", LanguageID= 115, Template= "", Example= "" },
                        new Language(){ Name= "VB.NET", Version= "mono-2.4.2.3", LanguageID= 101, Template= "", Example= "" },
                        new Language(){ Name= "Whitespace", Version= "wspace 0.3", LanguageID= 6, Template= "", Example= "" }
        };

        #endregion
    }
}
